package io.renren.modules.basedata.service.impl;

import cn.com.taiji.common.manager.net.http.binclient.ApiRequestException;
import cn.com.taiji.sdk.comm.LwClientHelper;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.*;
import io.renren.common.utils.GUID;
import io.renren.modules.basedata.dao.InternalInvoiceUploadDao;
import io.renren.modules.basedata.dao.OperlogDao;
import io.renren.modules.basedata.entity.tbl_InternalInvoice;
import io.renren.modules.basedata.entity.tbl_Operlog;
import io.renren.modules.basedata.service.InternalInvoiceUploadService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
public class InternalInvoiceUploadServiceImpl implements InternalInvoiceUploadService {
    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    InternalInvoiceUploadDao internalInvoiceUploadDao;
    @Autowired
    OperlogDao operlogDao;

    @Override
    public String billTransUpload() throws Exception {


        log.info("开始获取发票数据");

        List<tbl_InternalInvoice> list = null;

        tbl_InternalInvoice InternalInvoice = null;

        //获取未上传的省内发票数据
        list = getBillTrans();

        tbl_Operlog operlog = new tbl_Operlog();

        int operResult=0;
        Integer Count = 0;
        Long Amount = (long) 0;


        String FileName ="";
        String TollProvinceId  = "";

        //定义TransAction的List集合
        List<BillTransTransactionModel> listModelList= new ArrayList<BillTransTransactionModel>();

        if(list!=null&&list.size()>0){

            try{
                for(int i=0;i<list.size();i++){
                    //封装发票数据对象Transaction
                    InternalInvoice = list.get(i);
                    //定义Transaction对象
                    BillTransTransactionModel exitTransactionModel = new BillTransTransactionModel();
                    TollProvinceId = InternalInvoice.getTollProvinceId();
                    exitTransactionModel.setId(InternalInvoice.getId());
                    exitTransactionModel.setFeeId(InternalInvoice.getFeeId());
                    exitTransactionModel.setType(InternalInvoice.getType());
                    exitTransactionModel.setFee(InternalInvoice.getFee());
                    exitTransactionModel.setEnWeight(InternalInvoice.getEnWeight());
                    exitTransactionModel.setExWeight(InternalInvoice.getExWeight());
                    exitTransactionModel.setAxleCount(InternalInvoice.getAxleCount());
                    if(exitTransactionModel.getAxlsType() != null && exitTransactionModel.getAxlsType() != ""){
                        exitTransactionModel.setAxlsType(InternalInvoice.getAxlsType().toString());
                    }
                    exitTransactionModel.setPermittedWeight(InternalInvoice.getPermittedWeight());
                    exitTransactionModel.setEnTollLaneId(InternalInvoice.getEntryLaneID().toString());
                    exitTransactionModel.setEnTime(InternalInvoice.getEnTime());
                    exitTransactionModel.setEtcCardId(InternalInvoice.getEtcCardId());
                    exitTransactionModel.setCpcCardId(InternalInvoice.getCpcCardId());
                    exitTransactionModel.setSelfServiceCPC(InternalInvoice.getSelfServiceCPC());
                    exitTransactionModel.setElectricalPercentage(InternalInvoice.getElectricalPercentage());
                    exitTransactionModel.setEnVehicleId(InternalInvoice.getEnVehicleId());
                    exitTransactionModel.setExVehicleId(InternalInvoice.getExVehicleId());
                    exitTransactionModel.setIdentifyVehicleId(InternalInvoice.getIdentifyVehicleId());
                    exitTransactionModel.setEnVehicleType(InternalInvoice.getEnVehicleType());
                    exitTransactionModel.setExVehicleType(InternalInvoice.getExVehicleType());
                    exitTransactionModel.setSpecialType(InternalInvoice.getSpecialType().toString());
                    exitTransactionModel.setVehicleClass(InternalInvoice.getVehicleClass());
                    exitTransactionModel.setTerminalNo(InternalInvoice.getTerminalNo());
                    //入口收费站名称、出口收费站名称
                    exitTransactionModel.setEnTollStationName(InternalInvoice.getENTRYSTATIONNAME());
                    exitTransactionModel.setExTollStationName(InternalInvoice.getEXITSTATIONAME());
                    exitTransactionModel.setPayType(InternalInvoice.getPayType());
                    exitTransactionModel.setDescription(InternalInvoice.getDescription());
                    exitTransactionModel.setPointInfo(InternalInvoice.getPointInfo());
                    exitTransactionModel.setChargeRoute(InternalInvoice.getChargeRoute());
                    exitTransactionModel.setTollFee(InternalInvoice.getTollFee().toString());
                    exitTransactionModel.setDiscountFee(InternalInvoice.getDiscountFee().toString());
                    exitTransactionModel.setRateVersion(InternalInvoice.getRateVersion());
                    String jsonDetails = InternalInvoice.getRoadSplitDetail() ;
                    List<BillTransRoadSplitDetail> modellist = new  ArrayList<BillTransRoadSplitDetail>();

                    if(jsonDetails!=null || jsonDetails != ""){
                        //字符串转化为JSON数组对象
                        JSONArray jsonArray = JSONArray.fromObject(jsonDetails);
                        if(jsonArray!=null&&jsonArray.size()>0){
                            BillTransRoadSplitDetail model = new BillTransRoadSplitDetail();
                            for(int  n = 0; n <jsonArray.size(); n++){
                                JSONObject jsonObject = jsonArray.getJSONObject(n);
                                //为BillTransRoadSplitDetail对象赋值
                                model.setId(jsonObject.getString("id"));
                                model.setFee(jsonObject.getInt("fee"));
                                model.setSectionId(jsonObject.getString("sectionId"));
                                modellist.add(model);
                            }
                        }
                    }
                    exitTransactionModel.setRoadSplitDetail(modellist);
                    Count = Count + 1;
                    Amount = Amount + InternalInvoice.getFee();
                    listModelList.add(exitTransactionModel);
                }
                BillTransUploadRequest request = new BillTransUploadRequest();
                request.setTollProvinceId(TollProvinceId); //最后替换成Config.get
                request.setMessageId((long) 123);//包号，最后在公共的方法里去取
                request.setCount(Count);
                request.setAmount(Amount);
                request.setTransaction(listModelList);


                BillTransUploadResponse response = LwClientHelper.binPostUrl(request);
                log.info("发票数据上传信息返回结果:"+response.toJson());
                HashMap<String,String> map = new HashMap<String,String>();
                if(response!=null&&response.getInfo().equals("成功！")){
                    //上传成功后逐条更新上传状态
                    for(int i=0;i<list.size();i++){
                        map.put("id", list.get(i).getId());

                        if(internalInvoiceUploadDao.updateInternalInvoice(map)==1){

                            log.info("更新省内交易发票基础数据表上传标志成功");

                            operResult = 1;

                            operlog = getOperlog(32,1,list.get(i).getId(),FileName ,operResult, response.getInfo(),"上传成功,更新成功");
                        }else{

                            log.info("更新省内交易发票基础数据表上传标志失败");

                            operlog = getOperlog(32,1,list.get(i).getId(),FileName ,operResult, response.getInfo(),"上传成功,更新失败");
                            operlogDao.insertlog(operlog);
                            //sqlMapClient.insert("operlog_ORACLE.insertlog",operlog);
                        }

                    }

                }else{

                    log.info("上传发票基础数据信息失败,失败原因:"+response.toJson());

                    for(int i=0;i<list.size();i++){

                        map.put("id", list.get(i).getId());

                        if(internalInvoiceUploadDao.updateInternalInvoiceError(map)==1){

                            log.info("更新省内交易发票基础数据表上传标志成功");

                            operResult = 1;
                        }else{
                            log.info("更新省内交易发票基础数据表上传标志失败");
                        }
                    }

                    //getOperlog（操作类型,传输类型,发送文件名,接收文件名,操作结果,部中心返回结果,说明）
                    operlog = getOperlog(32,1,FileName,FileName,operResult, response.getInfo(),response.toJson());
                    operlogDao.insertlog(operlog);
                   // sqlMapClient.insert("operlog_ORACLE.insertlog",operlog);
                }
            }catch(IOException e){
                log.error("上传省内交易发票基础数据信息失败,失败原因:", e);
                operlog = getOperlog(32,1,FileName,FileName,operResult,"IO异常","上传省内交易发票基础数据信息失败,系统IO异常:"+e.getMessage());
                operlogDao.insertlog(operlog);
                //sqlMapClient.insert("operlog_ORACLE.insertlog",operlog);
                e.printStackTrace();
            }catch (ApiRequestException apie) {
                log.error("上传省内交易发票基础数据信息失败,失败原因:", apie);

                if(apie.getErrCode()>700&&apie.getErrCode()<800){
                    String str = apie.getMessage();
                    String[] errorList = str.split("ID:");
                    if(errorList!=null&&errorList.length>0){//如果存在异常数据
                        String errorID;
                        for (int i = 1 ; i <errorList.length ; i++ ) {
                            errorID = StringUtils.substringBefore(errorList[i], ",");//截取","之前的字符串
                            log.info("发票数据交易ID"+errorID+"上传失败！");
                            HashMap<String,String> map = new HashMap<String, String>();
                            map.put("id", errorID);
                            //更新该交易上传状态为9
                            if(apie.getErrCode()==704){//704：已存在
                                internalInvoiceUploadDao.updateInternalInvoiceError(map);
                                //sqlMapClient.update("transaction_ORACLE.updateInternalInvoiceError",map);
                            }else{
                                internalInvoiceUploadDao.updateInternalInvoiceError(map);
                                //sqlMapClient.update("transaction_ORACLE.updateInternalInvoiceError",map);
                            }
                        }
                    }
                }

                byte[] str = apie.getMessage().getBytes();
                if(str.length>1000){
                    operlog = getOperlog(32,1,FileName,FileName,operResult,String.valueOf(apie.getErrCode()),"上传省内交易发票基础数据信息,系统Apie异常:"+apie.getMessage().substring(0, 700));
                }else{
                    operlog = getOperlog(32,1,FileName,FileName,operResult,String.valueOf(apie.getErrCode()),"上传省内交易发票基础数据信息,系统Apie异常:"+apie.getMessage());
                }

                apie.printStackTrace();
            }
        }
        return "上传省内交易发票基础数据信息结束...";


    }

    //获取未上传的省内发票数据
    @SuppressWarnings("unchecked")
    public List<tbl_InternalInvoice> getBillTrans() throws Exception {
        List<tbl_InternalInvoice> list;
        try {
            list = internalInvoiceUploadDao.getBillTransList();
            //list = sqlMapClient.queryForList("transaction_ORACLE.getBillTransList");//
        } catch (Exception e1) {
            e1.printStackTrace();
            log.error("获取省内发票数据失败!错误信息:", e1);
            throw new Exception("获取省内发票数据交易信息失败:"+e1.getMessage());
        }
        return list;
    }

    //获取operlog信息
    public tbl_Operlog getOperlog(int operType,int softType,String sendFileName,String reFileName,int operResult,String reResult, String content){
        tbl_Operlog operlog = new tbl_Operlog();
        operlog.setWastesn(new GUID().toString());
        operlog.setOperTime(new Date());
        operlog.setOpertype(operType);
        operlog.setSoftType(softType);
        operlog.setSendFileName(sendFileName);
        operlog.setReFileName(reFileName);
        operlog.setOperResult(operResult);
        operlog.setReResult(reResult);
        operlog.setContent(content);
        return operlog;
    }

}
